home *** CD-ROM | disk | FTP | other *** search
/ MacWorld Secrets (4th Edition) / Mac Secrets CD 4th Ed.toast / Shareware & Freeware / KeyQuencer 1.2.2 / Developer’s toolkit / Common code / Extension.h < prev    next >
Text File  |  1995-12-16  |  24KB  |  422 lines

  1. // =============================================================================
  2. // KEYQUENCER EXTENSIONS HEADER - VERSION 1.2.2 - DECEMBER 1995
  3. // By Alessandro Levi Montalcini <alm@torino.alpcom.it>
  4. // ©1994-96 Binary Software, Inc. <binarysoft@eworld.com>
  5. // Don't forget to send us any cool extensions you create!
  6. // This text looks best in monaco 9 font, 4 spaces per tab, no wrapping
  7. //==============================================================================
  8. // Note that all the public interfaces that shipped with 1.2.1 are still good.
  9. // If you want to gain access to a KeyQuencer GluePtr from external software,
  10. // use the KQGestalt.c file provided with the new dev kit; it's a small piece of
  11. // code that works with both 1.2.X and 2.0 and returns a valid GluePtr or NIL.
  12. //==============================================================================
  13. #pragma once
  14. #ifndef _H_extension
  15. #define _H_extension
  16.  
  17. #ifndef __APPLEEVENTS__
  18. #include <AppleEvents.h>
  19. #endif
  20. //==============================================================================
  21. #if PRAGMA_ALIGN_SUPPORTED
  22. #pragma options align=mac68k
  23. #endif
  24. // =============================================================================
  25. // FORMAT OF THE MAIN ROUTINE FOR A KEYQUENCER EXTENSION:
  26. // pascal short main(long message, ParamsPtr params, MachineHandle mac, GluePtr glue);
  27.  
  28. typedef struct ParamsRec        ParamsRec, *ParamsPtr;
  29. typedef struct MachineRec        MachineRec, *MachinePtr, **MachineHandle;
  30. typedef struct GlueRec            GlueRec, *GluePtr;
  31. typedef struct EvtFilterRec        EvtFilterRec, *EvtFilterRecPtr;
  32.  
  33. typedef pascal short    (*ExtProcPtr)        (long message, ParamsPtr params, MachineHandle mac, GluePtr glue);
  34. typedef pascal Boolean    (*EvtFilterProcPtr)    (EventRecord *event, MachineHandle mac, GluePtr glue);
  35. typedef pascal OSErr    (*FinderSelHandler)    (long count, FSSpec items[], long reference, GluePtr glue);
  36.  
  37. // =============================================================================
  38. // CONSTANTS AND RESOURCE TYPES:
  39.  
  40. #define kExtensionResType 'KQex'    //  the extension res name (not file name)
  41.                                     //  is used by the macro interpreter
  42. #define kExtensionFileType 'KQex'    //  extension file type
  43. #define kExtensionCreator 'KQen'    //  extension file creator (standard icon)
  44. #define kMaxExtParams 32            //  max # of parameters passed to an extension
  45. #define kMaxScreens 3                //  max # of screens in the MachineRec record
  46.  
  47. #define kKeyFlowHPos -19715            //  key events are ignored by KeyQuencer if 
  48. #define kKeyFlowVPos -19949            //  event.where=={kKeyFlowHPos,kKeyFlowVPos}
  49.  
  50. // =============================================================================
  51. // MESSAGES (sent to the extension):
  52.  
  53. enum {
  54.     kExtMessageInit    = 'INIT',        //  setup extension, load resources;
  55.                                     //  no ParamsPtr available here
  56.     kExtMessageRun    = 'RUN '        //  run extension; the extension resource file
  57.                                     //  is already closed
  58. };
  59.  
  60. // WARNING: GLUE WAS NOT AVAILABLE AT INITIALIZE TIME IN KEYQUENCER 1.0 (now it is)
  61. // Check for nil glue before using glue routines in your kExtMessageInit handler
  62.  
  63. // =============================================================================
  64. // RESULT CODES (returned by the extension):
  65.  
  66. enum {
  67.     kExtNoError = 0,                //  no error
  68.     kExtCallMeAgain,                //  keep calling the extension over and over
  69.     kExtCallMeAgainLater,            //  call the extension again after all other
  70.                                     //  queued commands have executed
  71.     kExtUserAbortedMacro = 100,        //  code returned by LastMacroError when the
  72.                                     //  user aborts a macro with cmd-shift-return
  73.     kExtGenericError = 256,            //  positive results >= 256 stop macro execution
  74.     kExtBadEnvironment,                //  without informing the user (you may use
  75.     kExtBadParameters,                //  DisplayMessage or DisplayError to do so)
  76.     kExtTooManyParams,
  77.     kExtNotEnoughParams,
  78.     kExtUnknownKeyword,
  79.     kExtWrongApplication,
  80.     kExtNotEnoughMemory,
  81.     kExtObsoleteKeyQuencer,
  82.     kExtRequiresAppleEvents,
  83.     
  84.     kTellGenericError = -256,        //  negative results stop macro execution
  85.     kTellBadEnvironment,            //  and show a standard error message
  86.     kTellBadParameters,
  87.     kTellTooManyParams,
  88.     kTellNotEnoughParams,
  89.     kTellUnknownKeyword,
  90.     kTellWrongApplication,
  91.     kTellNotEnoughMemory,
  92.     kTellObsoleteKeyQuencer,
  93.     kTellRequiresAppleEvents
  94. };
  95.  
  96. // =============================================================================
  97. // CURRENT RECORD VERSIONS (will increase as I append more items to the records):
  98.  
  99. enum {
  100.     kCurParamsRecVers    = 1,
  101.     kCurMachineRecVers    = 1,
  102.     kCurGlueRecVers        = 6,        //  check the glue record version before using it
  103.     kCurRoutineCount    = 48        //  number of callback routines in the glue
  104. };
  105.  
  106. // =============================================================================
  107. // RECORD DEFINITIONS:
  108. // The current record contents will not be modified in future versions
  109. // although more items may be appended at the bottom of each record
  110.  
  111. struct ParamsRec {
  112.     short        paramsRecVers;                //  kCurParamsRecVers
  113.     short        paramsCount;                //  number of parameters passed
  114.     long        countCalls;                    //  this field is initially set to 0,
  115.                                             //  incremented at each kExtCallMeAgain,
  116.                                             //  always 1 after kExtCallMeAgainLater
  117.     long        firstCallTicks;                //  TickCount() of first time called
  118.                                             //  (reset when result != kExtCallMeAgain)
  119.     short        extensionKey;                //  keyCode<<8 + charCode (low word of
  120.                                             //  event.message of key down event)
  121.     short        extensionModifiers;            //  event.modifiers of the key down event
  122.                                             //  that invoked the macro
  123.     long        systemMemoryUsed;            //  you should add to this field the size of
  124.                                             //  any static handles and resources that
  125.                                             //  you allocate during kExtMessageInit
  126.     StringPtr    parameter[kMaxExtParams];    //  parameters are passed as read-only
  127.                                             //  pascal strings (including quotes if any);
  128.                                             //  all parameter processing is done by
  129.                                             //  the extension itself
  130. };
  131.  
  132. struct MachineRec {
  133.     short        machineRecVers;                //  kCurMachineRecVers
  134.     short        systemVersion;                //  system version in BCD format
  135.     short        screenCount;                //  # of screens connected to this machine
  136.     short        mainScreen;                    //  index of main screen in screenBounds array
  137.     Rect        screenBounds[kMaxScreens];    //  bounds of all available screens
  138.                                             //  (call UpdateMachineRec to validate bounds)
  139.     Boolean        hasGestalt;                    //  01
  140.     Boolean        hasWaitNextEvent;            //  02
  141.     Boolean        hasAppleEvents;                //  03
  142.     Boolean        has68020;                    //  04
  143.     Boolean        hasFPU;                        //  05
  144.     Boolean        hasColorQD;                    //  06  all these flags are automatically
  145.     Boolean        has32BitQD;                    //  07  set up by KeyQuencer so the extensions
  146.     Boolean        hasFSSpec;                    //  08  don't have to call Gestalt all the time
  147.     Boolean        hasNewStdFile;                //  09
  148.     Boolean        hasNotification;            //  10
  149.     Boolean        hasAliases;                    //  11
  150.     Boolean        hasFindFolder;                //  12
  151.     Boolean        hasPartialRes;                //  13
  152.     Boolean        hasSoundManager;            //  14
  153. };
  154.  
  155. struct GlueRec {
  156.     short                glueRecVers;            // check this before using recent callbacks
  157.     short                routineCount;            // don't check this
  158.     pascal void            (*DisplayMessage)        (ConstStr255Param message, Boolean playBeep);
  159.     pascal void            (*DisplayError)            (OSErr error);
  160.     pascal void            (*StopSequence)            (void);
  161.     pascal void            (*TypeString)            (ConstStr255Param string);
  162.     pascal void            (*TypeText)                (const unsigned char *text, short length);
  163.     pascal Boolean        (*SafePostEvent)        (const EventRecord *event);
  164.     pascal void            (*WaitTicks)            (long pause);
  165.     pascal short        (*ExecuteScript)        (Handle text);
  166.     pascal Boolean        (*ExtensionAvailable)    (ConstStr255Param name);
  167.     pascal void            (*GetCharacterInfo)        (unsigned char c, short *message, short *modifiers);
  168.     pascal Boolean        (*TrapAvailable)        (short trap);
  169.     pascal void            (*ShowStartupIcon)        (short iconID);
  170.     pascal void            (*AnonymousMessage)        (ConstStr255Param message, Boolean playBeep);
  171.     
  172. // the following routines are only available in glue version 2 or later (KQ 1.1 or later);
  173. // make sure that glue->glueRecVers >= 2 before using them:
  174.     
  175.     pascal Boolean        (*AppleEventsAvail)        (void);
  176.     pascal Boolean        (*SendAppleEvent)        (const AppleEvent *event, OSErr *errPtr, Boolean bringToFront);
  177.     pascal Boolean        (*WindowsAvailable)        (void);
  178.     pascal Boolean        (*MacroRunning)            (void);
  179.     pascal Boolean        (*EqualStringPartial)    (ConstStr255Param strToFind, ConstStr255Param strToSearch, Boolean caseSens, Boolean partialMatch);
  180.     pascal long            (*SearchString)            (ConstStr255Param strToFind, const unsigned char *buffer, long size, Boolean caseSens);
  181.  
  182. // the following routines are only available in glue version 3 or later (KQ 1.2 or later);
  183. // make sure that glue->glueRecVers >= 3 before using them:
  184.     
  185.     pascal WindowRef    (*RealFrontWindow)        (Boolean *isModalDialog);
  186.     pascal WindowRef    (*RealNextWindow)        (WindowRef baseWindow, Boolean *isModalDialog);
  187.     pascal Boolean        (*RealWindow)            (WindowRef window, Boolean *isModalDialog);
  188.     pascal OSErr        (*FindKQExtFolder)        (short *vRefNum, long *dirID);
  189.     pascal short        (*OpenExtResFile)        (void);
  190.     pascal void            (*UpdateMachineRec)        (void);
  191.     pascal Boolean        (*AskQuestion)            (ConstStr255Param question, ConstStr255Param okButtonTitle, ConstStr255Param cancelButtonTitle, short defaultButton, short numTextLines);
  192.     pascal Boolean        (*AskString)            (ConstStr255Param question, StringPtr answer, ConstStr255Param okButtonTitle, ConstStr255Param cancelButtonTitle, short defaultButton, short numInputLines);
  193.  
  194. // ==================== KeyQuencer 1.2.2 required below this point ====================
  195.  
  196. // the following routines are only available in glue version 5 or later (KQ 1.2.2 or later);
  197. // make sure that glue->glueRecVers >= 5 before using them:
  198.  
  199.     pascal short         (*CountMacros)            (void);
  200.     pascal Ptr            (*BuildSortedIndex)        (void);
  201.     pascal void            (*GetMacroInfo)            (short macroIndex, unsigned char *macroName, short *keyCode, short *modifiers);
  202.     pascal Handle        (*GetIndexedMacro)        (short macroIndex);
  203.     pascal Handle        (*GetNamedMacro)        (ConstStr31Param macroName);
  204.  
  205. // ===================== KeyQuencer 2.0 required below this point =====================
  206.  
  207. // the following routines are only available in glue version 6 or later (KQ 2.0 or later);
  208. // make sure that glue->glueRecVers >= 6 before using them:
  209.  
  210.     pascal Boolean        (*IsLiteralParameter)    (ConstStr255Param sourceParameter, StringPtr destString, short maxLength);
  211.     pascal Boolean        (*IsNumericParameter)    (ConstStr255Param sourceParameter, long *destNum, Boolean acceptNegative);
  212.     pascal Boolean        (*ProcessFinderSel)        (FinderSelHandler handler, long reference, OSErr *errptr);
  213.     pascal Boolean        (*KQAppleEventsBusy)    (void);
  214.     pascal OSErr        (*ExtractFileSpecs)        (ParamsPtr params, ConstStr255Param key1, ConstStr255Param key2, FSSpecPtr spec1, FSSpecPtr spec2, short defaultSpec);
  215.     pascal void            (*HoldDownModifiers)    (short modifiers);
  216.     pascal void            (*ReleaseModifiers)        (void);
  217.     pascal void            (*InstallEventFilter)    (EvtFilterRecPtr eventFilter);
  218.     pascal void            (*RemoveEventFilter)    (EvtFilterRecPtr eventFilter);
  219.     pascal DialogRef    (*GetDetachedDialog)    (Handle dlog, Handle ditl, WindowRef behind);
  220.     pascal short        (*LastMacroError)        (void);
  221.     pascal long            (*GetVariable)            (ConstStr255Param variableName, StringPtr variableValue);
  222.     pascal long            (*SetVariable)            (ConstStr255Param variableName, ConstStr255Param variableValue);
  223.     pascal long            (*ClearVariable)        (ConstStr255Param variableName);
  224.     pascal long            (*CountVariables)        (void);
  225.     pascal long            (*GetIndexedVariable)    (long variableIndex, StringPtr variableValue);
  226. };
  227.  
  228. struct EvtFilterRec {
  229.     EvtFilterRecPtr        nextFilter;        // for use by KQ only - always initialize to zero
  230.     EvtFilterProcPtr    filterProc;        // pointer to your event filter procedure
  231. };
  232.  
  233. // =============================================================================
  234. // GLUE - QUICK REFERENCE:
  235. /*
  236. DisplayMessage:        Displays a message (pascal string) via the notification mgr,
  237.                     optionally plays a system beep.
  238. DisplayError:        Displays an error (common OSErr's are shown by name in KQ 1.2).
  239. StopSequence:        Stops all macros and flushes the queue (same as cmd-shift-return).
  240. TypeString:            Types a pascal string as if the user was typing it from the keyboard.
  241. TypeText:            Same as TypeString, takes a buffer instead of a pascal string.
  242. SafePostEvent:        Checks the event queue and posts an event if it isn't already full
  243.                     (use this instead of PPostEvent); returns true if everything OK.
  244. WaitTicks:            Pauses macro execution for some time after the extension has returned.
  245. ExecuteScript:        Executes a macro (the macro text is passed in a handle);
  246.                     returns 0 if the macro was successfully queued,
  247.                     nonzero if an error was found (this is an internal error code).
  248. ExtensionAvailable:    Checks if an extension was loaded at startup.
  249. GetCharacterInfo:    Returns the keyCode, charCode and modifiers needed to type
  250.                     a given character with a keyDown event.
  251. TrapAvailable:        Checks if a trap is available (returns true if it is, false otherwise).
  252. ShowStartupIcon:    Displays a startup icon (this only works at startup time,
  253.                     when the init message is received by the extension).
  254. AnonymousMessage:    Displays a message (pascal string) without the extension name.
  255.  
  256. // the following routines are only available in glue version 2 or later (KQ 1.1 or later);
  257. // make sure that glue->glueRecVers >= 2 before using them:
  258.  
  259. AppleEventsAvail:    Returns true if the Engine process is running, false otherwise;
  260.                     SendAppleEvent can do without the Engine process under KQ 1.2 or later.
  261. SendAppleEvent:        Sends an Apple Event; the AppleEvent record is duplicated so it can
  262.                     be allocated on the stack, while the event data handle must be in
  263.                     the system zone and is disposed of automatically by SendAppleEvent;
  264.                     never call AEDisposeDesc on the AppleEvent after passing it to
  265.                     SendAppleEvent, since it's already called by KeyQuencer for you;
  266.                     *errPtr is set to 1 right away, and receives the error code when
  267.                     the event is later sent (pass nil if you don't care, but don't wait
  268.                     for this value to change inside a loop because the Engine process will
  269.                     wait and send the event when it gets some CPU time at WaitNextEvent);
  270.                     if bringToFront is true, the receiving application is switched to
  271.                     the foreground before the event is sent; SendAppleEvent returns
  272.                     true if the event was successfully queued (not sent), false otherwise.
  273. WindowsAvailable:    Returns true if QuickDraw and the Window Manager have been initialized.
  274. MacroRunning:        Returns true if KeyQuencer has more extensions to call or keystrokes
  275.                     to type inside its internal queues.
  276. EqualStringPartial:    Compares two strings with optional case sensitivity and partial
  277.                     matching (strToFind is a subset of strToSearch); returns true if equal.
  278. SearchString:        Searches a string inside a buffer with optional case sensitivity;
  279.                     returns the offset of the first matching character, or a negative
  280.                     number if no match was found.
  281.  
  282. // the following routines are only available in glue version 3 or later (KQ 1.2 or later);
  283. // make sure that glue->glueRecVers >= 3 before using them:
  284.  
  285. RealFrontWindow:    Returns the frontmost "real" window (uses RealWindow to filter
  286.                     out weird windows and floating palettes).
  287. RealNextWindow:        Returns the next "real" window behind a given base window.
  288. RealWindow:            Returns false for floating palettes, the desktop and other weird
  289.                     windows (this is an educated guess, not 100% reliable).
  290. FindKQExtFolder:    Finds the volume reference number and directory ID of the
  291.                     "KeyQuencer Extensions" folder.
  292. OpenExtResFile:        Opens the extension resource file; please don't use this if you can
  293.                     do without, since PowerBook users hate to have the HD spin up
  294.                     (the opened file is NOT guaranteed to be the same file that was
  295.                     loaded at startup: it may be an updated version, or another file
  296.                     with the same name that was copied into the "KeyQuencer Extensions"
  297.                     folder); returns refnum of resfile, or -1 if the file can't be opened.
  298. UpdateMachineRec:    Updates the machine record (the screen information fields may change
  299.                     after startup with the new Multiple Scan monitors).
  300. AskQuestion:        Displays an ok/cancel dialog and returns true if the "ok" button was
  301.                     pressed; returns false when the user cancels and when an error occurs;
  302.                     pass nil or an empty string to get the default button titles.
  303. AskString:            Displays a dialog with an editable text whose contents are copied
  304.                     from and passed back to the "answer" parameter; returns the same
  305.                     values you get from AskQuestion.
  306.  
  307. // ==================== KeyQuencer 1.2.2 required below this point ====================
  308.  
  309. // the following routines are only available in glue version 5 or later (KQ 1.2.2 or later);
  310. // make sure that glue->glueRecVers >= 5 before using them:
  311.  
  312. CountMacros:        Returns the number of KeyQuencer macros that are currently installed.
  313. BuildSortedIndex:    IMPORTANT: THE RETURNED POINTER IS CREATED IN THE SYSTEM HEAP AND MUST BE
  314.                     DISPOSED BY THE PROGRAM THAT REQUESTED IT.
  315.                     Creates an array of macro indexes that can be used to get the macros in
  316.                     alphabetical order (based on the macro names). There are CountMacros
  317.                     short words in the array, stored in a pointer in the system heap. You
  318.                     must call DisposePtr on the returned pointer when you're done with it.
  319. GetMacroInfo:        Given a zero-based index (from 0 to CountMacros-1), this call returns the
  320.                     macro name (a pascal string with up to 31 characters), the macro's key code
  321.                     (in the high byte of the returned word) and the macro's keystroke modifiers.
  322.                     Each of the three pointers may be NIL if you don't want the related data.
  323. GetIndexedMacro:    IMPORTANT: THE RETURNED HANDLE IS CREATED IN THE SYSTEM HEAP AND MUST BE
  324.                     DISPOSED BY THE PROGRAM THAT REQUESTED IT.
  325.                     Returns a handle containing the text of the nth macro, where n is a zero-
  326.                     based index (from 0 to CountMacros-1). Returns NIL if no such macro exists.
  327.                     Use DisposeHandle on the returned handle when you're done with it.
  328. GetNamedMacro:        IMPORTANT: THE RETURNED HANDLE IS CREATED IN THE SYSTEM HEAP AND MUST BE
  329.                     DISPOSED BY THE PROGRAM THAT REQUESTED IT (it used to be read-only in 2.0b2)
  330.                     Returns a handle containing the text of the macro whose name matches
  331.                     the "macroName" parameter; the name comparison is case-insensitive.
  332.                     Returns NIL if no macro with the given name is found. Use DisposeHandle on
  333.                     the returned handle when you're done with it.
  334.  
  335. // ===================== KeyQuencer 2.0 required below this point =====================
  336.  
  337. // the following routines are only available in glue version 6 or later (KQ 2.0 or later);
  338. // make sure that glue->glueRecVers >= 6 before using them:
  339.  
  340. IsLiteralParameter:    Checks if a parameter begins and ends with quotes; if so, it copies the
  341.                     unquoted literal to a destination string, up to a maximum of maxLength
  342.                     characters (plus one length byte at the beginning of the string).
  343. IsNumericParameter:    Checks if a parameter is an integer number, accepts negative numbers
  344.                     if acceptNegative is true; if it's a number, then the numeric value
  345.                     is copied in destValue and the function returns true.
  346. ProcessFinderSel:    Gets the current Finder selection and processes each item with the
  347.                     provided handler; the handler is not called right away, since the Engine
  348.                     process has to wait for the Finder's reply to a "get selection" event;
  349.                     the disposer is called once after the handler has been called for each
  350.                     selected item, so you get a chance to dispose of anything you stored in
  351.                     the reference parameter (which can be used freely); errptr behaves
  352.                     like in SendAppleEvent; the result is true if the handler was queued
  353.                     (requires the Engine process and Finder 7.5 or later).
  354. KQAppleEventsBusy:    Returns true if the KeyQuencer Engine Process is busy (i.e. if it has
  355.                     pending Apple Events in its queues).
  356. ExtractFileSpecs:    Interprets and removes file specifications from the parameters record
  357.                     passed to the extension; key1 and key2 are the keywords of the extension
  358.                     parameters (such as "from" and "to") that specify the usage of the file
  359.                     specifications; key1 is used by default if no key is found in the macro;
  360.                     defaultSpec is the number of the FSSpec to fill if no key is found (1 or
  361.                     2), or zero if a key is always required; the vRefNum of the FSSpec
  362.                     returned is 0 if no file was specified in the macro; the following
  363.                     parameters are removed from the ParamsRec: any literal parameter,
  364.                     clipboard, sysdisk, panels, apple, system, desktop, trash, extensions,
  365.                     preferences, startup (plus key1 and key2).
  366. HoldDownModifiers:    Disables all ADB devices whose original ADB address is 2 (which is the
  367.                     original address of all Apple keyboards) and updates the low-memory
  368.                     key map so that the desired modifier keys are held down; must be
  369.                     followed by a call to ReleaseModifiers, or the keyboard stays dead.
  370. ReleaseModifiers:    Releases the modifier keys that were pressed by a previous call to
  371.                     HoldDownModifiers and re-enables the disabled ADB devices.
  372. InstallEventFilter:    Installs an event filter procedure that gets called before KeyQuencer
  373.                     does its own event filtering; event filters can be installed and removed
  374.                     at any time (not only at startup) and should return true if the event
  375.                     they received must be killed (i.e. turned into a null event); note: the
  376.                     safest time to call RemoveEventFilter is from the filter itself (see below);
  377.                     the EvtFilterRec is owned by KeyQuencer until the filter is removed, and
  378.                     it can't be moved or disposed of (don't allocate it as a local variable
  379.                     on the stack!); it contains a pointer to the event filter routine and a
  380.                     pointer to the next EvtFilterRec which should be initialized to zero and
  381.                     never touched again, since it's used by KeyQuencer to build a linked list.
  382. RemoveEventFilter:    Removes an event filter procedure that was previously installed; it is
  383.                     usually a good idea to call RemoveEventFilter from inside the event filter
  384.                     itself, since the extension's "run" routine may not be called again even
  385.                     if you returned kExtCallMeAgain (the user could have stopped the macro
  386.                     before the extension was called again).
  387. GetDetachedDialog:    Behaves pretty much like GetNewDialog, except you pass it the handles to
  388.                     a DLOG template and a DITL template that you previously loaded into memory
  389.                     (typically at startup via GetResource + DetachResource). The DITL template
  390.                     is duplicated before being used, so that your copy of the handle is not
  391.                     disposed of when the dialog is later closed (since DisposeDialog frees up
  392.                     the memory used by the items list). Use DisposeDialog (not CloseDialog)
  393.                     to close the dialog when you're done with it.
  394. LastMacroError:        Returns the last error code returned by an extension or by the macro
  395.                     interpreter. Zero means no error, values > 256 or < 0 are extension
  396.                     errors, and small positive values are private error codes returned by
  397.                     the macro interpreter (syntax errors, etc). The kExtCallMeAgain and
  398.                     kExtCallMeAgainLater codes are reported as kExtNoError (i.e. zero).
  399. GetVariable:        Gets the value of a KeyQuencer variable. Returns the variable index or
  400.                     a negative value if the variable was not found. The variable name
  401.                     should not include the "$", "&" or "%" prefixes since these are stripped
  402.                     and used at runtime by the macro processor to quote the value if needed
  403.                     (the same rule applies to all the other variable routines as well).
  404. SetVariable:        Creates a KeyQuencer variable if no variable exists with the given name,
  405.                     then sets its value to the specified string. Returns the variable index
  406.                     or a negative value if an error occurred.
  407. ClearVariable:        Removes a variable. If variableName is NIL, all variables are removed.
  408.                     Returns the number of variables that were successfully removed.
  409. CountVariables:        Returns the number of KeyQuencer variables that are currently defined.
  410. GetIndexedVariable:    Same as GetVariable except it uses a numeric index instead of the name.
  411.                     Returns a negative value if the given index is out of range.
  412. */
  413. // =============================================================================
  414. #if PRAGMA_ALIGN_SUPPORTED
  415. #pragma options align=reset
  416. #endif
  417. //==============================================================================
  418.  
  419. #endif    // _H_extension
  420.  
  421. // =============================================================================
  422.